package cube

import (
	"fmt"
	"shqsoft.cn/pasnj/base"
	"shqsoft.cn/pasnj/bi/datapackage"
	"strconv"

	"github.com/go-redis/redis"
)

//Dimension 维度
type Dimension struct {
	setting     *datapackage.Dimension
	dimIndex    int
	redisIndex  int
	masterRedis *redis.Client
}

//NewHierarchy 根据名称创建维度层次对象
func (d *Dimension) NewHierarchy(name string) (*Hierarchy, error) {
	for i, hie := range d.setting.Hierarchies {
		if hie.Name == name {
			return newHierarchy(d, &hie, d.dimIndex, i, d.redisIndex), nil
		}
	}
	return nil, fmt.Errorf("指定维度层次%s不存在！", name)
}

func (d *Dimension) getAllLeafKeys() ([]string, error) {
	hie := d.setting.Hierarchies[0]
	hieObj := newHierarchy(d, &hie, d.dimIndex, 0, d.redisIndex)
	return hieObj.getAllLeafKeys()
}

func deleteByMatch(redisCli *redis.Client, pattern string) error {
	cursor := uint64(0)
	for {
		keys, cur, err := redisCli.Scan(cursor, pattern, 1000).Result()
		if err != nil {
			return fmt.Errorf("删除维度层次时，调用redis命令Scan出错:%s", err)
		}
		if len(keys) > 0 {
			_, err = redisCli.Del(keys...).Result()
			if err != nil {
				return fmt.Errorf("删除维度层次时，调用redis命令Del出错:%s", err)
			}
		}
		if cur == 0 {
			break
		}
		cursor = cur
	}
	return nil
}

//NewHierarchy 根据list表键删除hash
func deleteByList(redisCli *redis.Client, hkey string, lkey string) error {
	start := int64(0)
	eachCount := int64(1000)
	end := eachCount - 1
	count, err := redisCli.LLen(lkey).Result()
	if err != nil {
		return fmt.Errorf("执行deleteByList时，调用redis命令count出错:%s", err)
	}
	for {
		keys, err := redisCli.LRange(lkey, start, end).Result()
		if err != nil {
			return fmt.Errorf("执行deleteByList时，调用redis命令LRange出错:%s", err)
		}
		keyLen := len(keys)
		if keyLen == 0 {
			break
		}
		for i := 0; i < keyLen; i++ {
			keys[i] = hkey + keys[i]
		}
		_, err = redisCli.Del(keys...).Result()
		if err != nil {
			return fmt.Errorf("执行deleteByList时，调用redis命令Del出错:%s", err)
		}
		if end >= count {
			break
		}
		start += eachCount
		end += eachCount
	}
	return nil
}
func deleteByMaxIndex(redisCli *redis.Client, perf string, maxIndex int) error {
	start := 0
	eachCount := 1000
	end := eachCount - 1
	for {
		if end > maxIndex {
			end = maxIndex
		}
		keys := make([]string, end+1, end+1)
		for i := start; i <= end; i++ {
			keys[i] = perf + strconv.Itoa(i)
		}
		_, err := redisCli.Del(keys...).Result()
		if err != nil {
			return fmt.Errorf("执行deleteByMaxIndex时，调用redis命令Del出错:%s", err)
		}
		if end > maxIndex {
			break
		}
		start += eachCount
		end += eachCount
	}
	return nil
}

var dimsMap map[string]*Dimension
var timeDimName string

//GetDimensionObject 获取Dimension对象
func GetDimensionObject(name string) *Dimension {
	return dimsMap[name]
}

func init() {
	dp := datapackage.DefaultDP
	dimsMap = make(map[string]*Dimension)
	for i, dim := range dp.Dimensions {
		setting := dim
		dimObj := &Dimension{
			setting:     &setting,
			dimIndex:    i,
			redisIndex:  dim.RedisIndex,
			masterRedis: base.RedisClients[dim.RedisIndex],
		}
		dimsMap[dim.Name] = dimObj
		if dim.Type == "TimeDimension" {
			timeDimName = dim.Name
		}
	}
	cubeMap = make(map[string]*Cube)
	for _, cube := range dp.Cubes {
		cubeSetting := cube
		cubeR, err := newCube(&cubeSetting)
		if err != nil {
			panic(err)
		}
		cubeMap[cube.Name] = cubeR
	}
}
